package com.xmh.autocode.filecrate;

import com.xmh.autocode.inject.Inject;
import com.xmh.autocode.util.CreateUtils;
import com.xmh.autocode.util.NameUtils;
import com.xmh.autocode.vo.ColumnVo;
import com.xmh.autocode.vo.TableVo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;

import java.util.*;

import static java.lang.String.format;

public class VoCreate {

    /**
     * 创建实体类
     *
     * @param tableNameMaplist
     */
    public static void createEntity(List<TableVo> tableNameMaplist) {
        for (TableVo tableVo : tableNameMaplist) {
            // 转为驼峰
            String voName = NameUtils.nameTransformation(tableVo.getName());
            // 首字母大写
            String className = NameUtils.titleCase(voName) + "Entity";

            StringBuilder voClassFileSb = new StringBuilder();

            StringBuilder getVo = new StringBuilder();
            getVo.append(format("\tpublic %s(Map<String, Object> map) {\n", className));
            getVo.append("		if (map == null || map.isEmpty()) {\n");
            getVo.append("			return;\n");
            getVo.append("		}\n\n");

            voClassFileSb.append(format("package %s;\n\n", NameUtils.getPackagePath(Inject.getVo_Path())));
            voClassFileSb.append("import java.util.Date;\n");
            voClassFileSb.append("import java.math.BigDecimal;\n");
            voClassFileSb.append("import java.util.Map;\n");
            voClassFileSb.append("import java.util.HashMap;\n");
            voClassFileSb.append("import com.alibaba.fastjson.JSONObject;\n");
            voClassFileSb.append("import java.sql.Timestamp;\n");
            voClassFileSb.append("import lombok.Data;\n");
            voClassFileSb.append("import java.io.Serializable;\n\n");
            voClassFileSb.append("import io.swagger.annotations.ApiModelProperty;\n\n");

            voClassFileSb.append("@Data\n");
            voClassFileSb.append(format("public class %s implements Serializable {\n\n", className));

            long nextLong = new Random(System.currentTimeMillis()).nextLong();

            voClassFileSb.append("	/**\n");
            voClassFileSb.append("	 * 版本号\n");
            voClassFileSb.append(format("\t * 表备注：%s\n", tableVo.getRemarks()));
            voClassFileSb.append("	 */\n");
            voClassFileSb.append(format("\tpublic static final long serialVersionUID = %dL;\n\n", nextLong));

            StringBuilder voToMap = new StringBuilder();
            voToMap.append("    public Map<String, Object> toMap() {");
            voToMap.append("\n        Map<String, Object> map = new HashMap<>();");

            List<ColumnVo> list = tableVo.getColumnList();

//            List<ColumnVo> newList = new ArrayList<>();
//            CollectionUtils.addAll(newList, new Object[list.size()]);
//            Collections.copy(newList, list);
//            newList.add(new ColumnVo("page_index", "INT", ""));
//            newList.add(new ColumnVo("page_number", "INT", ""));

            for (ColumnVo columnVo : list) {
                // 字段名转为驼峰
                String cName = NameUtils.nameTransformation(columnVo.getName());

                // 转为对应的java类型
                String javaType = NameUtils.typeTransformation(columnVo.getType());

                String replace = columnVo.getRemarks().replace("\n", " ").replace("\r", " ");
                voClassFileSb.append(format("\t@ApiModelProperty(\"%s\")\n", replace));
                voClassFileSb.append(format("\tprivate %s %s;\n\n", javaType, cName));

                if ("String".equals(javaType)) {
                    getVo.append(format("\t\t%s = (String) map.get(\"%s\");\n\n", cName, cName));
                } else if ("Date".equals(javaType)) {
                    getVo.append(format("\t\tObject %sobj = map.get(\"%s\");\n", cName, cName));
                    getVo.append(format("\t\tif (%sobj != null) {\n", cName));
                    getVo.append(format("\t\t\tif (%sobj instanceof Date) {\n", cName));
                    getVo.append(format("\t\t\t\t%s = (Date) %sobj;\n", cName, cName));
                    getVo.append("			} else {\n");
                    getVo.append(format("\t\t\t\t%s = new Date((long) %sobj);\n", cName, cName));
                    getVo.append("			}\n");
                    getVo.append("		}\n\n");
                } else if ("BigDecimal".equals(javaType)) {
                    getVo.append(format("\t\tif (map.get(\"%s\") != null) {\n", cName));
                    getVo.append(format("\t\t\t%s = new BigDecimal(String.valueOf(map.get(\"%s\")));\n", cName, cName));
                    getVo.append("		}\n\n");
                } else {
                    getVo.append(format("\t\tif (map.get(\"%s\") != null) {\n", cName));
                    getVo.append(format("\t\t\t%s = %s.valueOf(String.valueOf(map.get(\"%s\")));\n", cName, javaType, cName));
                    getVo.append("		}\n\n");
                }

                voToMap.append(format("\n        map.put(\"%s\", %s);", cName, cName));
            }
            getVo.append("	}\n\n");

            voToMap.append("\n        return map;");
            voToMap.append("\n    }\n\n");

            voClassFileSb.append("	@SuppressWarnings(\"unchecked\")\n");
            voClassFileSb.append(format("\tpublic %s(String json) {\n", className));
            voClassFileSb.append("		this(JSONObject.parseObject(json, Map.class));\n");
            voClassFileSb.append("	}\n\n");
            voClassFileSb.append(format("\tpublic %s() {}\n\n", className));
            voClassFileSb.append(getVo);
            voClassFileSb.append(voToMap);

            voClassFileSb.append("\n}");

            CreateUtils.outFile(voClassFileSb.toString(), Inject.getVo_Path(), className, "java");
        }
    }

}
